/* =============================================================
 * System Name：Document Control System
 * File Name： OAuthDelegator.java
 * --------------------------------------------------------------
 * (C) Copyright M+W Group 2012 All Rights Reserved.
 *
 *  VERSION    DATE        BY                CHANGE/COMMENT
 * ----------------------------------------------------------------
 *
 */
package com.deco.authorization.api;

import java.util.Map;

import org.scribe.builder.ServiceBuilder;
import org.scribe.model.SignatureType;
import org.scribe.model.Token;
import org.scribe.model.Verifier;
import org.scribe.oauth.OAuthService;

import com.deco.authorization.user.OAuthUser;

public class OAuthDelegator {
	private Map<String, OAuthProvider> providers;
	private static final String REQUEST_TOKEN_KEY = "OAuthReqToken";

	/**
	 * According to oAuth specification, authorization URL will be returned for
	 * further external authorization.
	 * 
	 * @param provider
	 *            OAuth provider name
	 * @param tokenHolder
	 *            place the store the request token
	 * @return authorization url
	 */
	public String auth(String provider, Map tokenHolder) {
		OAuthProvider providerAPI = providers.get(provider);
		// throw exception if provider not found
		if (providerAPI == null) {
			throw new IllegalArgumentException("Error found. OAuth Provider "
					+ provider + " not found.");
		}

		// Proxy setting if any.
		// System.setProperty("http.proxyHost", "proxyde.mwgroup.local");
		// System.setProperty("http.proxyPort", "8080");

		OAuthService service = new ServiceBuilder().provider(
				providerAPI.getApi()).apiKey(providerAPI.getApiKey())
				.apiSecret(providerAPI.getApiSecret()).callback(providerAPI.getCallback()).signatureType(SignatureType.QueryString)
				.build();

		// Obtain the Request Token
		Token requestToken = service.getRequestToken();
		tokenHolder.put(REQUEST_TOKEN_KEY, requestToken);
		String authorizationUrl = service.getAuthorizationUrl(requestToken);
		return authorizationUrl;
	}

	public OAuthUser callback(Map parameters, String provider, Map tokenHolder) {
		OAuthProvider providerAPI = providers.get(provider);
		// throw exception if provider not found
		if (providerAPI == null) {
			throw new IllegalArgumentException("Error found. OAuth Provider "
					+ provider + " not found.");
		}

		// Proxy setting if any.
		// System.setProperty("http.proxyHost", "proxyde.mwgroup.local");
		// System.setProperty("http.proxyPort", "8080");

		OAuthService service = new ServiceBuilder().provider(
				providerAPI.getApi()).apiKey(providerAPI.getApiKey())
				.apiSecret(providerAPI.getApiSecret()).callback(providerAPI.getCallback()).signatureType(SignatureType.QueryString)
				.build();

		// Authorized token
		String[] authVerifier = (String[]) parameters.get(providerAPI
				.getAuthVerifier());
		Token requestToken = (Token) tokenHolder.get(REQUEST_TOKEN_KEY);
		if (authVerifier == null || authVerifier.length != 1) {
			throw new IllegalStateException("No authorizated");
		}

		Token accessToken = service.getAccessToken(requestToken, new Verifier(
				authVerifier[0]));

		return providerAPI.getUserPopulator().populateUser(accessToken,service);
	}

	public void setProviders(Map providers) {
		this.providers = providers;
	}

}
